package cn.lili.controller.wallet;

import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.vo.OrderSimpleVO;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.service.StoreService;
import cn.lili.modules.verification.entity.enums.VerificationEnums;
import cn.lili.modules.verification.service.VerificationService;
import cn.lili.modules.wallet.entity.dos.MemberWallet;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dos.WalletLog;
import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum;
import cn.lili.modules.wallet.entity.enums.WalletOwnerEnum;
import cn.lili.modules.wallet.entity.vo.MemberWalletVO;
import cn.lili.modules.wallet.service.MemberWalletService;
import cn.lili.modules.wallet.service.WalletLogService;
import cn.lili.modules.whitebar.entity.dos.Commission;
import cn.lili.modules.whitebar.entity.vo.CommissionVO;
import cn.lili.modules.whitebar.service.CommissionService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Pattern;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 买家端,会员余额接口
 *
 * @author pikachu
 * @since 2020/11/16 10:07 下午
 */
@RestController
@Api(tags = "商家端,会员余额接口")
@RequestMapping("/business/members/wallet")
public class MemberWalletBusinessController {

	/**
	 * 会员
	 */
	@Autowired
	private MemberService memberService;
	/**
	 * 会员余额
	 */
	@Autowired
	private MemberWalletService memberWalletService;
	/**
	 * 验证码
	 */
	@Autowired
	private VerificationService verificationService;

	// 佣金
	@Autowired
	private CommissionService commissionService;

	/**
	 * 订单
	 */
	@Autowired
	private OrderService orderService;
	@Autowired
	private WalletLogService walletLogService;

	/**
	 * 店铺
	 * 
	 * @return
	 */
	@Autowired
	private StoreService storeService;

	@GetMapping
	@ApiOperation(value = "查询会员预存款余额")
	@ApiImplicitParam(name = "owner", value = "钱包类型", required = true, dataType = "String", paramType = "query")
	public ResultMessage<MemberWalletVO> get(String owner) {
		AuthUser authUser = UserContext.getCurrentUser();
		if (authUser != null) {
			return ResultUtil.data(memberWalletService.getMemberWallet(authUser.getId(), owner));
		}
		throw new ServiceException(ResultCode.USER_NOT_LOGIN);
	}

	@RequestMapping(value = "/getCommission")
	@ApiOperation(value = "查询会员佣金总额")
	@ApiImplicitParam(name = "owner", value = "钱包类型", required = true, dataType = "String", paramType = "query")
	public ResultMessage<Double> getCommission(String owner) {
		AuthUser authUser = UserContext.getCurrentUser();
		if (authUser != null) {
			Double all = 0D;
			List<CommissionVO> commissionVOList = commissionService.findList(authUser.getId());
			if (commissionVOList != null) {
				for (CommissionVO commissionVO : commissionVOList) {
					all = CurrencyUtil.add(all, commissionVO.getTransactionFlow());
				}
			}
			return ResultUtil.data(all);
		}
		throw new ServiceException(ResultCode.USER_NOT_LOGIN);
	}

	@RequestMapping(value = "/getwallet")
	@ApiOperation(value = "查询本月佣金、本月流水、本月收入")
	public ResultMessage<Map<String, Object>> getCommissionMonth() {
		Map<String, Object> map = new HashMap<>();
		AuthUser authUser = UserContext.getCurrentUser();
		if (authUser != null) {
			// 获取当前月份
			Calendar cal = Calendar.getInstance();
			int year = cal.get(Calendar.YEAR);
			int month = cal.get(Calendar.MONTH) + 1;
			String m = year + "-" + (month < 10 ? "0" + month : month);

			// 佣金
			Double commissionAll = 0D;
			QueryWrapper<Commission> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("user_id", authUser.getId());
			queryWrapper.eq("DATE_FORMAT(create_time,'%Y-%m')", m);
			queryWrapper.orderByDesc("create_time");
			List<Commission> list1 = commissionService.list(queryWrapper);
			if (CollectionUtils.isNotEmpty(list1)) {
				for (Commission commission : list1) {
					commissionAll = CurrencyUtil.add(commissionAll,
							commission.getMember() != null ? commission.getMember() : commission.getTransactionFlow());
				}
			}
			map.put("commissionVOList", list1);
			map.put("commissionAll", commissionAll);

			// 收入
			Double incomeAll = 0D;
			QueryWrapper<Store> queryWrapper1 = new QueryWrapper<>();
			queryWrapper1.eq("member_id", authUser.getId());
			Store one = storeService.getOne(queryWrapper1);
			QueryWrapper<OrderSimpleVO> queryWrapper2 = new QueryWrapper<>();
			queryWrapper2.eq("o.store_id", one.getId());
			queryWrapper2.eq("DATE_FORMAT(o.payment_time,'%Y-%m')", m);
			List<OrderSimpleVO> orderSimpleList = orderService.queryByParamsList(queryWrapper2);
			if (CollectionUtils.isNotEmpty(orderSimpleList)) {
				for (OrderSimpleVO orderSimpleVO : orderSimpleList) {
					incomeAll = CurrencyUtil.add(incomeAll, orderSimpleVO.getFlowPrice());
				}
			}
			map.put("incomeList", orderSimpleList);
			map.put("incomeAll", incomeAll);

			// 支出
			Double payAll = 0D;
			QueryWrapper<Order> queryWrapper3 = new QueryWrapper<>();
			queryWrapper3.eq("member_id", authUser.getId());
			queryWrapper3.eq("DATE_FORMAT(create_time,'%Y-%m')", m);
			queryWrapper3.eq("owner", WalletOwnerEnum.RECHARGE.name());
			queryWrapper3.orderByDesc("create_time");
			List<Order> list = orderService.list(queryWrapper3);
			if (CollectionUtils.isNotEmpty(list)) {
				for (Order order : list) {
					payAll = CurrencyUtil.add(payAll, order.getFlowPrice());
				}
			}
			map.put("payList", list);
			map.put("payAll", payAll);
			return ResultUtil.data(map);
		}
		throw new ServiceException(ResultCode.USER_NOT_LOGIN);
	}

	@RequestMapping(value = "/set-password")
	@ApiOperation(value = "设置支付密码")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "password", value = "支付密码", required = true, dataType = "String", paramType = "query")})
	public ResultMessage<Object> setPassword(String password, @RequestHeader String uuid) {
		AuthUser authUser = UserContext.getCurrentUser();
		// 校验当前用户是否存在
		Member member = memberService.getById(authUser.getId());
		if (member == null) {
			throw new ServiceException(ResultCode.USER_NOT_EXIST);
		}
		// 校验验证码
		if (verificationService.check(uuid, VerificationEnums.WALLET_PASSWORD)) {
			memberWalletService.setMemberWalletPassword(member, password);
			throw new ServiceException(ResultCode.SUCCESS);
		} else {
			throw new ServiceException(ResultCode.VERIFICATION_ERROR);
		}

	}

	@RequestMapping(value = "/update-password/ordinary")
	@ApiOperation(value = "普通方式进行支付密码的修改")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "oldPassword", value = "旧支付密码", required = true, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "newPassword", value = "新支付密码", required = true, dataType = "String", paramType = "query")})
	public ResultMessage updatePassword(
			@RequestParam @Pattern(regexp = "[a-fA-F0-9]{32}", message = "旧密码格式不正确") String oldPassword,
			@RequestParam @Pattern(regexp = "[a-fA-F0-9]{32}", message = "新密码格式不正确") String newPassword) {
		AuthUser authUser = UserContext.getCurrentUser();
		// 校验当前用户是否存在
		Member member = memberService.getById(authUser.getId());
		if (member == null) {
			throw new ServiceException(ResultCode.USER_NOT_EXIST);
		}
		MemberWallet memberWallet = this.memberWalletService
				.getOne(new QueryWrapper<MemberWallet>().eq("member_id", member.getId()));
		// 校验新旧密码是否一致
		if (memberWallet != null) {
			if (!new BCryptPasswordEncoder().matches(oldPassword, memberWallet.getWalletPassword())) {
				throw new ServiceException(ResultCode.USER_OLD_PASSWORD_ERROR);
			}
			this.memberWalletService.setMemberWalletPassword(member, newPassword);
			return ResultUtil.data("修改成功");
		} else {
			throw new ServiceException(ResultCode.WALLET_NOT_EXIT_ERROR);
		}
	}

	@RequestMapping(value = "/check")
	@ApiOperation(value = "检测会员是否设置过支付密码,会员中心设置或者修改密码时使用")
	public Boolean checkPassword() {
		return memberWalletService.checkPassword();
	}

	@RequestMapping(value = "/withdrawal")
	@ApiOperation(value = "会员中心余额提现")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "price", value = "提现金额", required = true, dataType = "double", paramType = "query"),
			@ApiImplicitParam(name = "cardId", value = "提现目标id", required = true, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "owner", value = "来源", required = true, dataType = "String", paramType = "query")})
	public ResultMessage<MemberWithdrawApply> withdrawal(
			@Max(value = 9999, message = "充值金额单次最多允许提现9999元") @Min(value = 1, message = "充值金额单次最少提现金额为1元") Double price,
			String owner, String cardId) {
		return ResultUtil.data(memberWalletService.applyWithdrawal(price, owner, cardId));
	}

}
